package com.zhong.common.utils;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.zhong.common.annotation.QueryField;
import com.zhong.common.core.enums.QueryCondition;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;

@Slf4j
public class WrapperUtils {

    private static final String LANG_STRING ="java.lang.String";

    public static <T> Wrapper getWrapper(T entity) {
        QueryWrapper wrapper = new QueryWrapper();
        TableInfo tableInfo = TableInfoHelper.getTableInfo(entity.getClass());

        if (tableInfo != null) {
            for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
                try {
                    Field field = fieldInfo.getField();
                    Object value = field.get(entity);
                    // String类型：不为null且不为空字符串才拼接到sql中
                    if (LANG_STRING.equals(field.getType().getName())) {
                        if (null != value && !"".equals(value)) {
                            QueryField queryField = field.getAnnotation(QueryField.class);
                            if (queryField != null) {
                                wrapperValue(wrapper, queryField.condition(), fieldInfo.getColumn(), value);
                            } else {
                                wrapper.eq(fieldInfo.getColumn(), value);
                            }
                        }
                    } else {
                        if (value != null) {
                            QueryField queryField = field.getAnnotation(QueryField.class);
                            if (queryField != null) {
                                wrapperValue(wrapper, queryField.condition(), fieldInfo.getColumn(), value);
                            } else {
                                wrapper.eq(fieldInfo.getColumn(), value);
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }

            String keyColumn = tableInfo.getKeyColumn();

            List<Field> fieldList = ReflectionKit.getFieldList(ClassUtils.getUserClass(entity.getClass()));
            for (Field field : fieldList) {
                try {
                    field.setAccessible(true);
                    Object value = field.get(entity);
                    if (value == null) continue;

                    if (field.getName().equals(keyColumn)) {
                        wrapper.eq(keyColumn, value);
                        continue;
                    }

                    QueryField queryField = field.getAnnotation(QueryField.class);
                    if (queryField != null && StringUtils.isNotEmpty(queryField.fieldName())) {

                        TableFieldInfo f = null;
                        for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
                            if (fieldInfo.getField().getName().equals(queryField.fieldName()) && fieldInfo.getField().get(entity) == null) {
                                f = fieldInfo;
                                break;
                            }
                        }

                        if (f == null){
                            if(queryField.fieldName().equals(keyColumn)){
                                wrapperValue(wrapper, queryField.condition(), keyColumn, value);
                            }
                            continue;
                        }
                        wrapperValue(wrapper, queryField.condition(), f.getColumn(), value);
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        return wrapper;
    }

    public static <T> QueryWrapper getQueryWrapper(T entity) {
        return (QueryWrapper) getWrapper(entity);
    }

    public static <T> LambdaQueryWrapper<T> getLambdaQueryWrapper(T entity) {
        return getQueryWrapper(entity).lambda();
    }

    private static void wrapperValue(QueryWrapper wrapper, QueryCondition condition, String columnName, Object value) {
        switch (condition) {
            case like:
                wrapper.like(columnName, value);
                break;
            case likeLeft:
                wrapper.likeLeft(columnName, value);
                break;
            case likeRight:
                wrapper.likeRight(columnName, value);
                break;
            case eq:
                wrapper.eq(columnName, value);
                break;
            case ge:
                wrapper.ge(columnName, value);
                break;
            case le:
                wrapper.le(columnName, value);
                break;
            case gt:
                wrapper.gt(columnName, value);
                break;
            case lt:
                wrapper.lt(columnName, value);
                break;
            case notLike:
                wrapper.notLike(columnName, value);
                break;
            case ne:
                wrapper.ne(columnName, value);
                break;
            case in:
                if(value instanceof Collection){
                    Collection vs = (Collection)value;
                    wrapper.in(columnName,vs);
                }
//                wrapper.in(columnName,value);
                break;
            default:
                break;
        }
    }

}
